home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_02 / smith / calc9_11.c < prev    next >
Text File  |  1993-12-29  |  1KB  |  39 lines

  1. #define BASE  94        /* # possible output chars */
  2. #define FIRST_CODE  '!' /* lowest output char      */
  3. #define PBASE   56      /* prefix base             */
  4. #define BASESQ  (unsigned long)(BASE*BASE)
  5. #define MAKE_PRINT(c)  (char)((c)+FIRST_CODE)
  6. #define CV2ASCII(p,v)  (*(p)=MAKE_PRINT((v)/BASE), \
  7.                         *(p+1)=MAKE_PRINT((v)%BASE))
  8. #define PBMULT (unsigned)(((0xffffffffUL/PBASE)>>16)+1)
  9. ...
  10. /* Encode 9 bytes into 11 printable ASCII chars.    */
  11.    unsigned long block; /* conversion area      */
  12.    int         i;       /* input byte index     */
  13.    unsigned int qb = 0; /* prefixes             */
  14.    ldiv_t      ld;      /* quotient, remainder  */
  15.  
  16.    for (i = 1; i < 9; i += 4) {
  17.       unsigned    q;
  18.       block = ((unsigned long)
  19.                (((unsigned)in[i+0]<<8) | in[i+1])<<16)+
  20.               (((unsigned) in[i+2]<<8) | in[i+3]);
  21.  
  22.       q = (unsigned) (block >> 16) / PBMULT;
  23.       block = block- ((unsigned long)(q*PBMULT) << 16);
  24.       ld = ldiv ((long) block, (long) BASESQ);
  25.       CV2ASCII(out+i+2, (unsigned) ld.quot);
  26.       CV2ASCII(out+i+4, (unsigned) ld.rem);
  27.       qb = qb * PBASE + q;
  28.    }
  29.  
  30.    /* Now convert the remaining byte and prefixes
  31.     * from previous block conversions               */
  32.    block = ((unsigned long) qb << 8) | in[0];
  33.    ld = ldiv ((long) block, (long) BASESQ);
  34.    out[0] = MAKE_PRINT((unsigned) ld.quot);
  35.    CV2ASCII(out+1, (unsigned) ld.rem);
  36.  
  37. /* End of File */ 
  38.  
  39.